package controller;

import bean.common.CommonResult;
import entity.mongo.User;
import enumration.AuthorityEnum;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.ReactiveSecurityContextHolder;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;
import service.security.UserSecurityService;

//@CrossOrigin(origins = "*", maxAge = 3600)
@RestController
//@RequestMapping
public class UserController {
    @Autowired
    private UserSecurityService userService;

    @RequestMapping(value = "auth/login")
    public Mono<CommonResult<String>> login(@RequestBody User user) {
        if (user == null || user.getUsername() == null || user.getPassword() == null) {
            return Mono.just(CommonResult.failed());
        }

        return userService.login(user);
//        return Mono.just(CommonResult.failed("password is unvalid"));
    }
    @RequestMapping(value = "auth/register")
    public Mono<CommonResult<User>> register(@RequestBody User user) {
        if (user == null || user.getUsername() == null || user.getPassword() == null) {
            return Mono.just(CommonResult.failed());
        }
        return userService.register(user);
    }

    @RequestMapping("test")
    @PreAuthorize("hasRole('VIP')")//
//    @PreAuthorize(value = "hasPermission('ADMIN')")
    public Mono<SecurityContext> test(ServerWebExchange exchange) {
        Mono<SecurityContext> context = ReactiveSecurityContextHolder.getContext();
        context.subscribe(System.out::println);
//                .switchIfEmpty(Mono.error(new IllegalStateException("ReactiveSecurityContext is empty")))
//                .map(SecurityContext::getAuthentication)
//                .map(Authentication::getPrincipal)
//                .cast(User.class);
//        System.out.println(userMono);

//        Mono<SecurityContext> context = ReactiveSecurityContextHolder.getContext();
//        Flux<User> userFlux = userService.userList();
        return context;
    }

    @RequestMapping(value = "upgrade/{level}")
    public Mono<CommonResult<User>> upgrade(@PathVariable Integer level) {
        Mono<SecurityContext> context = ReactiveSecurityContextHolder.getContext();
        return context.flatMap(s -> {
            UsernamePasswordAuthenticationToken authentication = (UsernamePasswordAuthenticationToken) s.getAuthentication();
            AuthorityEnum authorityEnum;
            if (level == 1) {
                authorityEnum = AuthorityEnum.VIP;
            } else if (level == 2) {
                authorityEnum = AuthorityEnum.SUPER_VIP;
            } else {
                return Mono.just(CommonResult.failed("error"));
            }
            return userService.upgrade((String) authentication.getPrincipal(), authorityEnum).map(CommonResult::success);
//            return Mono.just(CommonResult.failed("error"));
        });



//        return userService.upgrade(userMono, authorityEnum);

    }
}
